package cn.com.infcn.spider.scheduler;

import java.util.List;
import java.util.Map;

import cn.com.infcn.spider.domain.Doc;
import cn.com.infcn.spider.domain.Job;
import cn.com.infcn.spider.io.input.Input;
import cn.com.infcn.spider.io.input.InputFactory;
import cn.com.infcn.spider.io.input.Pageable;
import cn.com.infcn.spider.io.output.OutputFactory;
import cn.com.infcn.spider.util.JythonRunner;

/**
 * 简单的Scheduler模板类实现。
 * @author mixl
 * 
 * 使用说明:
 * 子类需要实现方法innerExplain。
 * 用户通过实现接口{@link cn.com.infcn.spider.io.input.Pageable#iterator()}，按分页方式返回数据
 * 或者 实现接口{@link cn.com.infcn.spider.io.input.Input#all()}，一次返回所有数据
 * @author mixl
 *
 */
public abstract class SimpleScheduler extends Scheduler {
	
	static boolean isRuning = false;

	private boolean flag = false;

	public SimpleScheduler(Job job) {
		super(job);
	}

	@Override
	public void run() {
		isRuning = true;
		try {
	
			long sleepTime = ((Job) job).getSleepTime();
	
			flag = sleepTime > 0;
	
			do {
	
				for (Input input : inputs) {
					if (input instanceof Pageable) {
	
						Pageable itInput = (Pageable) input;
	
						while (true) {
							List<?> list = itInput.iterator();
							if (list == null || list.size() == 0) {
								break;
							}
							explain(list);
	
						}
					} else {
						List<?> list = input.all();
	
						if (list == null || list.size() == 0) {
							break;
						}
	
						explain(list);
					}
	
				}
	
				try {
					flush();
				} catch (Exception e1) {
					e1.printStackTrace();
					LOG.error(e1);
					return;
				}
	
				if (sleepTime > 0) {
					try {
						Thread.sleep(sleepTime);
					} catch (InterruptedException e) {
						e.printStackTrace();
						LOG.error(e);
						return;
					}
				}
			} while (flag);
	
		} finally {
			isRuning = false;
		}
	}

	@Override
	public void shutdown() {
		try {
			super.shutdown();
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error(e);
		}
		flag = false;
	}
	
	@Override
	public boolean isRuning() {
		return isRuning;
	}

	@Override
	protected void init() {
		inputs = InputFactory.create(job.getInput(), job.getName());
		outputs = OutputFactory.create(job.getOutput(), job.getName());
	}

	@Override
	public Object test(String uri) {
		// TODO Auto-generated method stub
		return null;
	}

	protected void explain(List<?> list) {
		for (Object obj : list) {
			Doc record = innerExplain(obj);
			output(record);
		}
	}

	/**
	 * 使用脚本对每条记录进行处理
	 * @param obj
	 * @return
	 */
	protected abstract Doc innerExplain(Object obj);

	/**
	 * 解释执行jython脚本
	 * @param map 脚本执行当中需要的上下文对象集
	 * @param script 脚本
	 */
	protected void parse(Map<String, Object> map, String script) {
		JythonRunner.run(map, script);
	}

}